local L = LibStub("AceLocale-3.0"):GetLocale("AzCastBarOptions")
do
	local class = select(2,UnitClass("player"));
	if (class == "MAGE" or class == "WARLOCK" or class == "PRIEST") then
		return;
	end
end

local GetTime = GetTime;
local FormatTime = AzCastBar.FormatTime;

-- Extra Options
local extraOptions = {
	{
		[0] = L["Additional"],
		{ type = "Color", var = "colNormal", default = { 0.4, 0.6, 0.8, 1 }, label = L["Swing Bar Color"] },
	},
};

-- Variables
local b = AzCastBar.CreateBar();
local pName = UnitName("player");
local prefix, suffix;
local spellSwingReset = {
	[GetSpellInfo(78)] = true,		-- Heroic Strike
	[GetSpellInfo(845)] = true,		-- Cleave
	[GetSpellInfo(1464)] = true,	-- Slam
	[GetSpellInfo(2973)] = true,	-- Raptor Strike
	[GetSpellInfo(6807)] = true,	-- Maul
	[GetSpellInfo(56815)] = true,	-- Rune Strike
};

-- Localized Names
local autoShot = GetSpellInfo(75);
local meleeSwing = GetLocale() == "enUS" and "Melee Swing" or GetSpellInfo(6603);

--------------------------------------------------------------------------------------------------------
--                                           Frame Scripts                                            --
--------------------------------------------------------------------------------------------------------

local function OnUpdate(self,elapsed)
	-- Update Bar
	if (not b.fadeTime) then
		b.timeProgress = (GetTime() - b.startTime);
		b.timeLeft = max(0,b.maxValue - b.timeProgress);

		b.status:SetValue(b.maxValue - b.timeLeft);
		b.time:SetText(FormatTime(b.timeLeft)..(b.cfg.showTotalTime and " / "..FormatTime(b.maxValue,1) or ""));

		if (b.timeLeft == 0) then
			b.fadeTime = b.cfg.fadeTime;
		end
	-- Fade
	elseif (b.fadeElapsed < b.fadeTime) then
		b.fadeElapsed = (b.fadeElapsed + arg1);
		b:SetAlpha(b.cfg.alpha - b.fadeElapsed / b.fadeTime * b.cfg.alpha);
	else
		b:Hide();
	end
end

--------------------------------------------------------------------------------------------------------
--                                           Event Handling                                           --
--------------------------------------------------------------------------------------------------------

local function StartSwing(time,text)
	b.maxValue = time;
	b.name:SetText(text);
	b.startTime = GetTime();
	b.status:SetMinMaxValues(0,time);
	b.status:SetStatusBarColor(unpack(b.cfg.colNormal));
	b.fadeTime = nil;
	b.fadeElapsed = 0;
	b:SetAlpha(b.cfg.alpha);
	b:Show();
end

-- Combat Log Parser
local function OnCombatLogEvent(self,event,time,type,sourceGUID,sourceName,sourceFlags,destGUID,destName,destFlags,...)
	-- Something our Player does
	if (sourceName == pName) then
		prefix, suffix = type:match("(.-)_(.+)");
		if (prefix == "SWING") then
			StartSwing(UnitAttackSpeed("player"),meleeSwing);
		end
	-- Something Happens to our Player
	elseif (destName == pName) then
		prefix, suffix = type:match("(.-)_(.+)");
		if (prefix == "SWING") and (suffix == "MISSED") and (b.maxValue) and (select(1,...) == "PARRY") then
			b.maxValue = (b.maxValue - (b.startTime + b.maxValue - GetTime()) * 0.5);
			b.status:SetMinMaxValues(0,b.maxValue);
			b.status:SetStatusBarColor(1.0,0.75,0.5,1.0);
		end
	else
		return;
	end
end

-- OnEvent
local function OnEvent(self,event,...)
	if (event == "COMBAT_LOG_EVENT_UNFILTERED") then
		OnCombatLogEvent(self,event,...);
	elseif (event == "UNIT_SPELLCAST_SUCCEEDED") then
		local unit, spell = ...;
		if (unit == "player") then
			if (spell == autoShot) then
				StartSwing(UnitRangedDamage("player"),spell);
			elseif (spellSwingReset[spell]) then
				StartSwing(UnitAttackSpeed("player"),meleeSwing);
			end
		end
	end
end

-- OnConfigChanged
function b:OnConfigChanged(cfg,barId)
	if (cfg.enabled) then
		b:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
		b:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED");
	else
		b:UnregisterAllEvents();
	end
end

--------------------------------------------------------------------------------------------------------
--                                        Init AzCastBar Entry                                        --
--------------------------------------------------------------------------------------------------------

b.token = L["Swing"];
b.options = extraOptions;
b:SetPoint("CENTER",0,140);
b.icon:SetTexture("Interface\\Icons\\Spell_Shadow_SoulLeech_2");
b:SetScript("OnUpdate",OnUpdate);
b:SetScript("OnEvent",OnEvent);
tinsert(AzCastBar.frames,b);